/**
 * @brief
 * @details   自旋锁
 * @author    Yin
 * @version   1.0
 * @date
 * @copyright
 * @note
 */

#ifndef SPINLOCK_H
#define SPINLOCK_H

#include <QObject>

#include <atomic>

/**
 * @brief  自旋锁
 */
class SpinLock {

public:
    /**
     * @brief   SpinLock 默认构造
     */
    SpinLock() = default;

    /**
     * @brief   SpinLock 移除拷贝
     */
    SpinLock(const SpinLock&) = delete;

    /**
     * @brief   SpinLock 移除拷贝
     */
    SpinLock& operator=(const SpinLock&) = delete;

    /**
     * @brief   Lock 上锁
     */
    void Lock()
    {
        while (m_lockFlag.test_and_set(std::memory_order_acquire)) {}
    }

    /**
     * @brief   UnLock 解锁
     */
    void UnLock()
    {
        m_lockFlag.clear(std::memory_order_release);
    }

private:
    /** 锁-原子变量
     */
    std::atomic_flag m_lockFlag = ATOMIC_FLAG_INIT;
};

class SpinLockHolder
{
public:
    /**
     * @brief   SpinLockHolder 构造函数
     * @param   lock 锁变量
     */
    SpinLockHolder(SpinLock* lock) :
        mLockFlag(lock)
    {
        mLockFlag->Lock();
    }

    /**
     * @brief   ~SpinLockHolder 析构函数
     */
    ~SpinLockHolder()
    {
        mLockFlag->UnLock();
    }

    /**
     * @brief   isAvailable 是否有效
     * @return  bool
     */
    bool isAvailable() const
    {
        return mLockFlag != NULL;
    }

private:
    /** 锁变量
     */
    SpinLock* mLockFlag;
};

#endif // SPINLOCK_H
